﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GameLibrary.Unit
{
    using Tile;

    /// <summary>
    /// Blueprint of a unit
    /// </summary>
    [Serializable]
    public class Template
    {
        #region variables

        /// <summary>
        /// Health point.
        /// </summary>
        public uint HP { get; private set; }
        /// <summary>
        /// Supply point. 
        /// How long a unit can last while stay out of player's cities.
        /// </summary>
        public uint SP { get; private set; }
        /// <summary>
        /// Action point
        /// How many action it can perform.
        /// </summary>
        public uint AP { get; private set; }
        /// <summary>
        /// Attack ability.
        /// </summary>
        public uint Attack { get; private set; }
        /// <summary>
        /// Defence ability.
        /// Reduce attack and bombard damage.
        /// </summary>
        public uint Defence { get; private set; }
        /// <summary>
        /// Range of attack.
        /// </summary>
        public uint AttackRange { get; private set; }
        /// <summary>
        /// How far it can see.
        /// </summary>
        public uint Sight { get; private set; }

        public uint Cost { get; private set; }
        #region flags

        public UnitActionFlags Actions { get; private set; }

        #endregion

        #endregion

        #region constructor

        public Template(
            uint hp,
            uint sp, 
            uint ap, 
            uint attack, 
            uint defence,
            uint attackRange, 
            uint sight,
            UnitActionFlags actions 
                )
        {
            this.HP = hp;
            this.SP = sp;
            this.AP = ap;
            this.Attack = attack;
            this.Defence = defence;
            this.AttackRange = attackRange;
            this.Sight = sight;
            this.Actions = actions;
            this.Cost = this.GetTotalCost();
        }

        #endregion

        #region get total

        /// <summary>
        /// Total points * cost per point
        /// </summary>
        /// <returns></returns>
        private uint GetTotalCost()
        {
            uint ap = this.GetCost(AP);
            uint hp = this.GetCost(HP);
            uint sp = this.GetCost(SP);
             uint ar =  this.GetCost(AttackRange);
             uint s = this.GetCost(Sight);
             uint at = this.GetCost(Attack);
             uint de = this.GetCost(Defence);
             uint total = ap + sp + hp + ar + s + at + de;
            // attack, move and fortify is default to all units
            if (this.Actions.HasFlag(UnitActionFlags.Explore) == true)
                total+=UnitHelper.CostPerPoint;
            if (this.Actions.HasFlag(UnitActionFlags.Build) == true)
                total+=UnitHelper.CostPerPoint;
            if (this.Actions.HasFlag(UnitActionFlags.Resupply) == true)
                total+=UnitHelper.CostPerPoint;
            return total;
        }

        private uint GetCost(uint number)
        {
            return number * UnitHelper.CostPerPoint;
        }
        #endregion

        #region default templates

        public static Template DefaultSoldier
            = new Template(2, 0, 1, 1, 1, 0, 0, UnitActionFlags.Default);
        public static Template DefaultScout
            = new Template(1, 1, 1, 0, 0, 0, 1, UnitActionFlags.Default | UnitActionFlags.Explore);
        public static Template DefaultLabor
            = new Template(1, 1, 2, 0, 0, 0, 0, UnitActionFlags.Default | UnitActionFlags.Build);
        public static Template AllActions
            = new Template(5, 5, 5, 5, 5, 5, 5, UnitActionFlags.All);
        #endregion
    }
}
